package postgres

import (
	"gorm.io/gorm"
	"strings"
	"time"
)

// 一段时间内的数量
type DurationCount struct {
	Point time.Time
	Count int64
}

type DurationCounts []DurationCount

func (d DurationCounts) Len() int {
	return len(d)
}

func (d DurationCounts) Swap(i, j int) {
	d[i], d[j] = d[j], d[i]
}

func (d DurationCounts) Less(i, j int) bool {
	return d[i].Point.Before(d[j].Point)
}

func queryCount(db *gorm.DB, raw string, begin, end time.Time) (counts DurationCounts, err error) {
	now := time.Now()
	// 如果查询的时候在当前月份，定位到当前时间
	if begin.Year() == now.Year() && begin.Month() == now.Month() {
		end = now
	}
	rows, err := db.Raw(raw, begin.Unix(), end.Unix()).Rows()
	timeMap := make(map[string]DurationCount)
	defer rows.Close()
	for rows.Next() {
		var count DurationCount
		err = rows.Scan(&count.Point, &count.Count)
		if err != nil {
			return counts, err
		}
		timeMap[count.Point.Format("2006-01-02")] = count
	}
	// 一个月的数据
	if strings.Contains(raw, "day") {
		days := end.YearDay() - begin.YearDay()
		counts = make([]DurationCount, days)
		for i := 0; i < days; i++ {
			day := begin.AddDate(0, 0, i)
			if c, ok := timeMap[day.Format("2006-01-02")]; ok {
				counts[i] = c
			} else {
				counts[i] = DurationCount{
					Point: day,
					Count: 0,
				}
			}
		}
		// 最多12个月并且begin end只会在同一年
	} else if strings.Contains(raw, "month") {
		// 包含当前月份
		months := end.Month() - begin.Month() + 1
		counts = make([]DurationCount, months)
		for i := 0; i < int(months); i++ {
			month := begin.AddDate(0, i, 0)
			if c, ok := timeMap[month.Format("2006-01-02")]; ok {
				counts[i] = c
			} else {
				counts[i] = DurationCount{
					Point: month,
					Count: 0,
				}
			}
		}
		// 往前推五年
	} else if strings.Contains(raw, "year") {
		counts = make([]DurationCount, 5)
		for i := 0; i < 5; i++ {
			year := begin.AddDate(i, 0, 0)
			if c, ok := timeMap[year.Format("2006-01-02")]; ok {
				counts[i] = c
			} else {
				counts[i] = DurationCount{
					Point: year,
					Count: 0,
				}
			}
		}
	}
	return counts, err
}
func queryCountWithTotal(db *gorm.DB, raw string, begin, end time.Time, total int64) (counts DurationCounts, err error) {
	counts, err = queryCount(db, raw, begin, end)
	now := time.Now()
	for i := 0; i < len(counts); i++ {
		total += counts[i].Count
		if counts[i].Point.Before(now) {
			counts[i].Count = total
		}
	}
	return counts, err
}
